package org.common.utils.tool;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

/**
 * @author zhouzhibing
 * @date 2025/3/5
 */
public class TestTool {

    /**
     * 单线程处理测试
     * @param desc 描述
     * @param testCount 测试次数
     * @param roundCount 轮数
     * @param consumer 处理方法
     */
    public static void doHandler(String desc , long testCount , int roundCount , Consumer<Integer> consumer) {
        for (int i = 0; i < testCount; i++) {
            consumer.accept(i);
        }
        long totalUseTime = 0;
        for (int i = 0; i < roundCount; i++) {
            long startTime = System.currentTimeMillis();
            for (int j = 0; j < testCount; j++) {
                consumer.accept(i);
            }
            long useTime = System.currentTimeMillis() - startTime;
            System.out.println(desc + ", useTime : " + useTime + ", testCount : " + testCount);
            totalUseTime += useTime;
        }
        System.out.println(roundCount + ", total usage time: " + totalUseTime + ", Average usage time: " + (totalUseTime / roundCount));
    }

    /**
     * 多线程处理测试
     * @param desc 描述
     * @param testCount 测试次数
     * @param roundCount 轮数
     * @param consumer 处理方法
     */
    public static void doMultiThreadHandler(String desc , int testCount , int roundCount , Consumer<Integer> consumer) {
        for (int i = 0; i < testCount; i++) {
            consumer.accept(i);
        }

        long totalUseTime = 0;
        int cpuCount = Runtime.getRuntime().availableProcessors();
        ExecutorService executorService = Executors.newFixedThreadPool(cpuCount);
        try(executorService) {
            for (int i = 0; i < roundCount; i++) {
                final int index = i;
                CountDownLatch countDownLatch = new CountDownLatch(testCount);
                long startTime = System.currentTimeMillis();

                for (int j = 0; j < testCount; j++) {
                    executorService.execute(() -> consumer.accept(index));
                    countDownLatch.countDown();
                }

                try {
                    countDownLatch.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                long useTime = System.currentTimeMillis() - startTime;
                System.out.println(desc + ", useTime : " + useTime + ", testCount : " + testCount);
                totalUseTime += useTime;
            }
            System.out.println(roundCount + ", total usage time: " + totalUseTime + ", Average usage time: " + (totalUseTime / roundCount));
        }
    }
}
